# coding=utf-8

from flask import session
from typing import Callable
from logging import Logger

from app.cores.variable import Variable
from app.cores.parser import new_parse_data as _p
from app.cores.dictionaries import ELEMENT_TYPE, LOGIC_CONTROLLER_TYPE
from app.models import LogicController, IfController, WhileController, LoopController, SimpleController


def exec_logic_controller(recursive_func, logic_controller, logger):
    """
    执行逻辑控制器
    :param recursive_func: 递归执行函数
    :type recursive_func:  Callable[[int], None]
    :param logic_controller: 逻辑控制器
    :type logic_controller: LogicController
    :param logger: 日志
    :type logger: Logger
    """

    if logic_controller.logic_controller_type == LOGIC_CONTROLLER_TYPE.IF_CONTROLLER:
        logger.info('[IF控制器][表达式内容:%s]' % logic_controller.specific_controller.expression)
        exec_if_controller(recursive_func=recursive_func, if_controller=logic_controller.specific_controller)
    elif logic_controller.logic_controller_type == LOGIC_CONTROLLER_TYPE.WHILE_CONTROLLER:
        logger.info('[WHILE控制器][表达式内容:%s]' % logic_controller.specific_controller.expression)
        exec_while_controller(recursive_func=recursive_func, while_controller=logic_controller.specific_controller)
    elif logic_controller.logic_controller_type == LOGIC_CONTROLLER_TYPE.LOOP_CONTROLLER:
        logger.info('[LOOP控制器][循环次数:%s]' % logic_controller.specific_controller.expression)
        exec_loop_controller(recursive_func=recursive_func, loop_controller=logic_controller.specific_controller)
    elif logic_controller.logic_controller_type == LOGIC_CONTROLLER_TYPE.SIMPLE_CONTROLLER:
        logger.info('[SIMPLE控制器]')
        exec_simple_controller(recursive_func=recursive_func, simple_controller=logic_controller.specific_controller)


def exec_simple_controller(recursive_func, simple_controller):
    """
    执行简单控制器
    :param recursive_func: 递归执行函数
    :type recursive_func:  Callable[[int], None]
    :param simple_controller: 简单控制器
    :type simple_controller: SimpleController
    """
    # 直接执行该简单控制器下的所有组件
    recursive_func(logic_controller_id=simple_controller.logic_controller.id)


def exec_if_controller(recursive_func, if_controller):
    """
    执行if控制器判断
    :param recursive_func: 递归执行函数
    :type recursive_func:  Callable[[int], None]
    :param if_controller: if控制器
    :type if_controller: IfController
    """

    def _eval_if_controller_expression(expression):
        """
        执行if控制的表达式
        :param expression: IF控制器表达式
        :type expression: str
        :return: True or False
        :rtype: bool
        """
        if expression.strip() == '':
            return False
        else:
            glb = {}
            loc = {}
            loc['vars'] = Variable.get_project_variable(session.get('project_id'))
            return bool(eval(_p(expression), glb, loc))

    # 获取if控制数据
    if_controller_expression = if_controller.expression
    if _eval_if_controller_expression(if_controller_expression):
        # 执行逻辑控制器下所有组件
        recursive_func(logic_controller_id=if_controller.logic_controller.id)


def exec_while_controller(recursive_func, while_controller):
    """
    执行While控制器判断
    :param recursive_func: 递归执行函数
    :type recursive_func:  Callable[[int], None]
    :param while_controller: While控制器
    :type while_controller: WhileController
    """

    def _eval_while_controller_expression(expression):
        """
        执行While控制的表达式
        :param expression: While控制器表达式
        :type expression: str
        :return: True or False
        :rtype: bool
        """
        if expression.strip() == '':
            return False
        else:
            glb = {}
            loc = {}
            loc['vars'] = Variable.get_project_variable(session.get('project_id'))
            return bool(eval(_p(expression), glb, loc))

    # 获取While控制数据
    while_controller_expression = while_controller.expression
    while _eval_while_controller_expression(while_controller_expression):
        # 执行逻辑控制器下所有组件
        recursive_func(logic_controller_id=while_controller.logic_controller.id)


def exec_loop_controller(recursive_func, loop_controller):
    """
    执行Loop控制器判断
    :param recursive_func: 递归执行函数
    :type recursive_func:  Callable[[int], None]
    :param loop_controller: Loop控制器
    :type loop_controller: LoopController
    """

    def _eval_loop_controller_expression(expression):
        """
        获取Loop控制器循环次数
        :param expression: Loop控制器表达式
        :type expression: str
        :return: 循环次数
        :rtype: int
        """
        if expression.strip() == '':
            return 0
        else:
            glb = {}
            loc = {}
            loc['vars'] = Variable.get_project_variable(session.get('project_id'))
            return int(eval(_p(expression), glb, loc))

    for _ in range(_eval_loop_controller_expression(loop_controller.expression)):
        # 执行逻辑控制器下所有组件
        recursive_func(logic_controller_id=loop_controller.logic_controller.id)
